﻿using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.Context;
using Dexter.Logger.Concretes;
using Dexter.Logger.Contracts;

namespace Dexter.Dependency.Castle.Resolver {
	public class LoggerSubDependencyResolver : ISubDependencyResolver {
		readonly IKernel kernel;
		ILoggerFactory loggerFactory;

		public ILoggerFactory LoggerFactory {
			get { return loggerFactory ?? ( loggerFactory = kernel.Resolve <ILoggerFactory> ( ) ); }
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="T:System.Object"/> class.
		/// </summary>
		public LoggerSubDependencyResolver ( IKernel kernel ) {
			this.kernel = kernel;
		}

		/// <summary>
		/// Should return an instance of a service or property values as
		///             specified by the dependency model instance. 
		///             It is also the responsibility of <see cref="T:Castle.MicroKernel.IDependencyResolver"/>
		///             to throw an exception in the case a non-optional dependency 
		///             could not be resolved.
		/// </summary>
		/// <param name="context">Creation context, which is a resolver itself</param><param name="contextHandlerResolver">Parent resolver - normally the IHandler implementation</param><param name="model">Model of the component that is requesting the dependency</param><param name="dependency">The dependency model</param>
		/// <returns>
		/// The dependency resolved value or null
		/// </returns>
		public object Resolve ( CreationContext context , ISubDependencyResolver contextHandlerResolver , ComponentModel model , DependencyModel dependency ) {
			if (CanResolve ( context, contextHandlerResolver, model, dependency )) {
				if (LoggerFactory != null) {
					if (dependency.TargetType == typeof ( ILogger )) {
						
						return LoggerFactory.Create ( model.Implementation );
					}
				}
				return NullLogger.Instance;
			}
			return null;
		}

		/// <summary>
		/// Returns true if the resolver is able to satisfy this dependency.
		/// </summary>
		/// <param name="context">Creation context, which is a resolver itself</param><param name="contextHandlerResolver">Parent resolver - normally the IHandler implementation</param><param name="model">Model of the component that is requesting the dependency</param><param name="dependency">The dependency model</param>
		/// <returns>
		/// <c>true</c> if the dependency can be satisfied
		/// </returns>
		public bool CanResolve ( CreationContext context , ISubDependencyResolver contextHandlerResolver , ComponentModel model , DependencyModel dependency ) {
			return dependency.TargetType == typeof ( ILogger ) || dependency.TargetType == typeof ( ILogger );
		}
	}
}
